package com.smart.stock.module.maindata.services;

import com.alibaba.fastjson.JSONArray;
import com.smart.stock.module.maindata.entity.StockCompany;
import com.smart.stock.module.maindata.entity.StockPriceDaily;
import com.smart.stock.common.util.DateUtils;
import com.smart.stock.common.util.h2.H2Util;
import com.smart.stock.common.util.spring.EntityUtil;
import com.smart.stock.module.spider.jobSpiderApi.TushareApi;
import com.smart.stock.module.spider.util.TradingDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * ${DESCRIPTION}
 *
 * @author chenguoxiang
 * @create 2019-06-11 17:09
 **/
@Slf4j
@Service
public class StockDailyPriceServices {
    @Autowired
    private TradingDateUtil tradingDateUtil;
    @Autowired
    private TushareApi tushareApi;
    @Autowired
    private MongoTemplate template;
    @Autowired
    private TushareApi tushareSpider;

    public void refreshCodeListDailyPriceToMax(String[] codes) throws Exception {
        for (int i = 0; i < codes.length; i++) {
            String code = codes[i];
            refreshDailyPriceToMax(code);
        }

    }

    public void refreshDailyPriceToMax(String code) throws Exception {
        String entityName = EntityUtil.getEntityNameByCode(StockPriceDaily.class,code);
        if (!H2Util.tableExist(entityName)) {
            H2Util.createH2TableFromMongo(template, StockPriceDaily.class,code);
        }
        String sql = String.format("select max(tradeDate) max_tradedate from %s where code = '%s'",entityName,code);
        ResultSet resultSet = H2Util.execQuerySQL(sql);
        int max_tradedate = 0;
        while(resultSet.next()) {
            max_tradedate = resultSet.getInt("max_tradedate");
        }

        String maxdate = DateUtils.current_date().replace("-", "");
        refreshDailyPrice(code,String.valueOf(max_tradedate),maxdate);
    }

        /**
         * 刷新指定日期指定代码的日线数据
         * @param code 代码
         * @param start 开始时间
         * @param end 结束时间
         */
    public void refreshDailyPrice(String code,String start,String end){
        Criteria cr = new Criteria();
        Criteria c1 = Criteria.where("tradeDate").gte(Integer.valueOf(start));
        Criteria c2 = Criteria.where("tradeDate").lt(Integer.valueOf(end));
        Criteria c3 = Criteria.where("code").is(code);
        Criteria criteria = cr.andOperator(c1, c2, c3);

//        List<StockPriceDaily> list = template.find(new Query(criteria), StockPriceDaily.class);
//        System.out.println(list);

        template.remove(new Query(criteria), StockPriceDaily.class);

        JSONArray data= tushareApi.getStockDailyPrice(TushareApi.formatCode(code),start,end);
        BulkOperations ops = template.bulkOps(BulkOperations.BulkMode.UNORDERED, "stock_price_daily");
        for (int i = 0; i < data.size(); i++) {
            JSONArray row =data.getJSONArray(i);
            if (row != null && row.size()>0) {
                StockPriceDaily daily = new StockPriceDaily();
                daily.setCode(code);
                daily.setTradeDate(row.getInteger(1));
                daily.setOpen(row.getDouble(2));
                daily.setClose(row.getDouble(5));
                daily.setHigh(row.getDouble(3));
                daily.setLow(row.getDouble(4));
                daily.setChange(row.getDouble(7));
                daily.setPctchg(row.getDouble(8));
                daily.setVol(row.getDouble(9));
                daily.setAmount(row.getDouble(10));
                ops.insert(daily);
            }
        }
        if (data.size()>0) ops.execute();


    }

    /**
     * 刷新所有股票的日线数据
     */
    public void initDailyPrice(){
        String startDate= tradingDateUtil.minusDateNow(1,0,0,"yyyyMMdd");
        String end=tradingDateUtil.getDateYYYYMMdd();
        List<StockCompany> list = new ArrayList<StockCompany>();
        JSONArray rows_sh =tushareSpider.getStockShCompany();
        JSONArray rows_sz =tushareSpider.getStockSZCompany();
        //先删除再新增
        template.dropCollection(StockPriceDaily.class);
        for (int i = 0; i < rows_sh.size(); i++) {
            String code=rows_sh.getJSONArray(i).getString(0).replaceAll("\\D+","");
            System.out.println(String.format("更新sh股票价格数据，代码为%s,i=%s==========",code,i));
            refreshDailyPrice(code,startDate,end);
        }
        for (int i = 0; i < rows_sz.size(); i++) {
            String code=rows_sz.getJSONArray(i).getString(0).replaceAll("\\D+","");
            System.out.println(String.format("更新sz股票价格数据，代码为%s,i=%s==========",code,i));
            refreshDailyPrice(code,startDate,end);
        }

//        template.insertAll(list);

    }

    /**
     * 统计日线数据行数
     * @param code
     * @return
     */
    public Long getStockDailyRows(String code){
       return template.count(new Query(Criteria.where("code").is(code)), StockPriceDaily.class);
    }

    /**
     * 得到日线数据
     * @param code
     * @return
     */
    public List<StockPriceDaily> getDailyLine(String code){
        return template.find(new Query(Criteria.where("code").is(code)).with(Sort.by(Sort.Direction.ASC, "tradeDate")),StockPriceDaily.class);
    }

    public List<StockPriceDaily> getDataByDate(String tradeDate){
        return template.find(new Query(Criteria.where("tradeDate").is(tradeDate)),StockPriceDaily.class);
    }
}
